import React, { useState, useCallback } from 'react';

import styles from './useReducer.css';

/**
 * 模拟 react hooks 内置的 useReducer
 * 底层还是依赖一个 useState 状态，但是不暴露 setState，
 * 而只能通过 dispatch(action) 间接的受控的更新 state。
 * @param reducer
 * @param initState
 */
function useReducer(reducer: Function, initState: any) {
  const [state, setState] = useState(initState);
  const dispatch = useCallback(
    (action: any) => {
      setState(reducer(state, action));
    },
    [state],
  );
  return [state, dispatch];
}

function numberReducer(n: number = 0, action: any) {
  switch (action.type) {
    case 'inc':
      return n + 1;
    case 'dec':
      return n - 1;
    case 'double':
      return n * 2;
    default:
      return n;
  }
}

export default function() {
  const [n, dispatch] = useReducer(numberReducer, 10);
  return (
    <div className={styles.normal}>
      <h1>Page useReducer n={n}</h1>
      <button onClick={() => dispatch({ type: 'inc' })}>inc</button>
      <button onClick={() => dispatch({ type: 'dec' })}>dec</button>
      <button onClick={() => dispatch({ type: 'double' })}>double</button>
    </div>
  );
}
